module AboutYou
  module SDK
    module Model
      module FacetManager
        ###
        # This class is responsible for handling all the logic when working with
        # Facets
        #
        # author:: Collins GmbH & Co KG
        ###
        class DefaultFacetManager
          # the duration for the cached values to live
          DEFAULT_CACHE_DURATION = 7200

          # a Hash containing instances of AboutYou::SDK::Model::Facet
          attr_accessor :facets
          # an Instance of a class of AboutYou::SDK::CacheProvider
          attr_accessor :cache
          # The key for which the values are stored in the cache
          attr_accessor :cache_key
          # an Instance of AY
          attr_accessor :shop_api

          ###
          # the Constructor for the DefaultFacetManager class
          #
          # * *Args*    :
          #   - +cache+ -> The cache client set on the AY class
          #   - +app_id+ -> The App-Id of the App
          #   - +shop_api+ -> an Instance of AY
          #
          # * *Returns* :
          #   - Instance of AboutYou::SDK::Model::CategoryManager::DefaultFacetManager
          ###
          def initialize(cache = nil, app_id = '', shop_api)
            self.cache     = cache
            self.facets    = {}
            self.shop_api  = shop_api
            self.cache_key = 'AY:SDK:' + String(app_id) + ':facets'

            load_cached_facets
          end

          ###
          # Gets the cached Categories for this app
          #
          # * *Returns* :
          #   - True/False determining whether the loading was sucessfull or not
          ###
          def load_cached_facets
            parse_json(
              cache.get(cache_key),
              shop_api.model_factory_instance
            ) if cache && cache.exists(cache_key)
          end

          ###
          # this method caches a given json_object
          #
          # * *Args*    :
          #   - +json_object+ -> the jsonObject received from the api
          #
          # * *Returns* :
          #   - True/False determining whether the setting was sucessfull or not
          ###
          def cache_facets(json_object)
            cache.set(cache_key, json_object, DEFAULT_CACHE_DURATION)
          end

          ###
          # This method clears the cache
          #
          # * *Returns* :
          #   - True/False determining whether the clearing was sucessfull or not
          ###
          def clear_cache
            cache.delete(cache_key)
          end

          ###
          # this method parses a json object received from the api and
          # creates models from it
          #
          # * *Args*    :
          #   - +json_object+ -> the jsonObject received from the api
          #   - +factory+ -> the model factory used for creating the models
          #
          # * *Returns* :
          #   - Instance of AboutYou::SDK::Model::CategoryManager::DefaultFacetManager
          ###
          def parse_json(json_object, factory, query = nil)
            return unless facets.empty? && json_object
            cache_facets(json_object) if cache
            self.facets = factory.create_facets_list(json_object, query)
          end

          ###
          # this method checks whether this facet manager has read-in
          # facets or not
          #
          # * *Returns* :
          #   - a boolean which determines whether this facet Manager has read-in facets or not
          ###
          def empty?
            facets.empty?
          end

          ###
          # This method is used for getting a facet model by a given group_id and facetId
          #
          # * *Args*    :
          #   - +group_id+ -> the group id for which a facet model should be returned
          #   - +id+ -> the facet id for which a facet model should be returned
          #
          # * *Returns* :
          #   - either an instance of AboutYou::SDK::Model::Facet or nil if +group_id+ or +id+ is not found
          ###
          def facet(group_id, id)
            look_up_key = AboutYou::SDK::Model::Facet.new(
              0,
              '',
              [],
              0,
              ''
            ).unique_key(group_id, id)
            facets[look_up_key] ? facets[look_up_key] : nil
          end

          ###
          # This method is used for getting all facets for an Array of group ids
          #
          # * *Args*    :
          #   - +group_ids+ -> an Array containing group ids for which facet models should be returned
          #
          # * *Returns* :
          #   - a Hash containing pairs of facetId => instance of AboutYou::SDK::Model::Facet
          ###
          def facets_by_group_ids(group_ids = [])
            group_ids = group_ids.map { |gId| Integer(gId) }
            facets.select { |_key, facet| group_ids.include?(facet.group_id) }
          end
        end
      end
    end
  end
end
